library(dplyr)
library(readr)
library(tidyverse)
library(ggplot2)
library(highcharter)
library(magrittr)
data <- read_csv("https://raw.githubusercontent.com/Alexburk93/Data_Wrangling_EDA/main/data/suicide_analysis.csv")
New names:Rows: 894 Columns: 22── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (13): Country name, Code, Indicator Name, Indicator Code, VAR, Variable, MEA, Measure, ISIC4...17, ISIC4...18, U...
dbl  (9): Year, Age-standardized suicide rate - Sex: both sexes, Life Ladder, Social support, Healthy life expectanc...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
                data %>% sample_n(19)

Renaming variables and drop unwanted columns

# renaming the columns 
data <- data %>%
  rename(`Country_name` = `Country name`,
         `Suicide_Rate` = `Age-standardized suicide rate - Sex: both sexes`,
         `Life_ladder` = `Life Ladder`,
         `Social_support` = `Social support`,
         `Life_expectancy` = `Healthy life expectancy at birth`,
         `Freedom_choices` = `Freedom to make life choices`,
         `Corruption` = `Perceptions of corruption`,
         `Indicator_name` = `Indicator Name`,
         `Indicator_code` = `Indicator Code`)

# drop columns 
# remove the original 'Time' column
data <- select(data, -Variable, -ISIC4...17, -ISIC4...18, -VAR, -MEA, -`Unit Code`)  
data
head(data)
# change names
names(data) <- make.names(names(data))
# dimensions of the dataframe
nrow(data)
[1] 894
ncol(data)
[1] 16
dim(data)
[1] 894  16
# check the structure of the object
str(data)
tibble [894 × 16] (S3: tbl_df/tbl/data.frame)
 $ Country_name   : chr [1:894] "Australia" "Australia" "Australia" "Australia" ...
 $ Code           : chr [1:894] "AUS" "AUS" "AUS" "AUS" ...
 $ Year           : num [1:894] 2011 2011 2011 2011 2011 ...
 $ Suicide_Rate   : num [1:894] 10.1 10.1 10.1 10.1 11 ...
 $ Life_ladder    : num [1:894] 7.41 7.41 7.41 7.41 7.19 ...
 $ Social_support : num [1:894] 0.967 0.967 0.967 0.967 0.954 ...
 $ Life_expectancy: num [1:894] 72.3 72.3 72.3 72.3 72.1 ...
 $ Freedom_choices: num [1:894] 0.945 0.945 0.945 0.945 0.935 ...
 $ Corruption     : num [1:894] 0.382 0.382 0.382 0.382 0.269 ...
 $ Indicator_name : chr [1:894] "GDP (current US$)" "GDP (current US$)" "GDP (current US$)" "GDP (current US$)" ...
 $ Indicator_code : chr [1:894] "NY.GDP.MKTP.CD" "NY.GDP.MKTP.CD" "NY.GDP.MKTP.CD" "NY.GDP.MKTP.CD" ...
 $ GDP            : num [1:894] 1.40e+12 1.40e+12 1.40e+12 1.40e+12 1.68e+11 ...
 $ Measure        : chr [1:894] "Index 2007=100" "Index 2007=100" "Index 2007=100" "Index 2007=100" ...
 $ Unit           : chr [1:894] "Index" "Index" "Index" "Index" ...
 $ Value          : num [1:894] 132 138 143 145 122 ...
 $ Quarter        : chr [1:894] "Q1" "Q2" "Q3" "Q4" ...
# look at columns 6, 7 and 10
head(data[ , c(2, 4:6, 12, 15)])
# look at columns 6, 7 and 10
tail(data[ , c(1, 3, 9)])
table(data$Year)

2011 2012 2013 2014 2015 2016 2017 2018 2019 
 100  100  100  100  100  100  100   97   97 
data %>% 
  select(Country_name) %>% 
  unique() %>% 
  nrow()
[1] 19
unique(data$Country_name)
 [1] "Australia"      "New Zealand"    "United States"  "Spain"          "Netherlands"    "France"        
 [7] "Finland"        "Belgium"        "Japan"          "South Africa"   "Iceland"        "Norway"        
[13] "Sweden"         "Italy"          "Brazil"         "United Kingdom" "Germany"        "Canada"        
[19] "Denmark"       
unique(data$Year)
[1] 2011 2012 2013 2014 2015 2016 2017 2018 2019
# Set highcharter options for tooltip decimals
options(highcharter.tooltip.valueDecimals = 2)

# Create highcharter map visualization
hc <- highchart() %>%
  hc_add_series_map(
    worldgeojson, data, value = "GDP", 
    joinBy = c('name', 'Country_name'),
    name = "GDP (current US$)"
  )  %>% 
  hc_colorAxis(stops = color_stops()) %>% 
  hc_title(text = "World Map") %>% 
  hc_subtitle(text = "GDP in current US$")

hc
# Set highcharter options for tooltip decimals
options(highcharter.tooltip.valueDecimals = 2)

# Create map visualizations for each variable
hc_life_expectancy <- highchart() %>%
  hc_add_series_map(
    worldgeojson, data, 
    value = "Life_expectancy", 
    joinBy = c('name', 'Country_name'),
    name = "Life Expectancy"
  ) %>%
  hc_colorAxis(stops = color_stops()) %>%
  hc_title(text = "World Map") %>%
  hc_subtitle(text = "Life Expectancy")

hc_suicide_rates <- highchart() %>%
  hc_add_series_map(
    worldgeojson, data, 
    value = "Suicide_Rate", 
    joinBy = c('name', 'Country_name'),
    name = "Suicide Rates"
  ) %>%
  hc_colorAxis(stops = color_stops()) %>%
  hc_title(text = "World Map") %>%
  hc_subtitle(text = "Suicide Rate")

hc_corruption <- highchart() %>%
  hc_add_series_map(
    worldgeojson, data, 
    value = "Corruption", 
    joinBy = c('name', 'Country_name'),
    name = "Corruption"
  ) %>%
  hc_colorAxis(stops = color_stops()) %>%
  hc_title(text = "World Map") %>%
  hc_subtitle(text = "Corruption")

# Display the map visualizations
list(hc_life_expectancy, hc_suicide_rates, hc_corruption)
[[1]]

[[2]]

[[3]]
NA

AVG GDP over years

Calculation

avg_gdp_per_year <- data %>% 
  group_by (`Year`) %>% 
  summarise(avg_gpd = mean(`GDP`))

avg_gdp_per_year

Plot

ggplot(avg_gdp_per_year, aes(x = Year, y = avg_gpd)) +
  geom_line(color = "blue") +  
  labs(title = "Average GDP Over Time worldwide",
       x = "Year",
       y = "GDP") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_gdp_per_year$Year), max(avg_gdp_per_year$Year), by = 1))

AVG Happiness over years

Calculation

avg_happiness_per_year <- data %>% 
  group_by (`Year`) %>% 
  summarise(avg_happinnes = mean(`Life_ladder`, na.rm = T))

avg_happiness_per_year

Plot

ggplot(avg_happiness_per_year, aes(x = Year, y = avg_happinnes)) +
  geom_line(color = "blue") +  
  labs(title = "Average Happiness Over Time worldwide",
       x = "Year",
       y = "Happiness") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_happiness_per_year$Year), max(avg_happiness_per_year$Year), by = 1))

AVG Suicide Rates over years

Calculation

avg_Suicide_Rate_per_year <- data %>% 
  group_by (`Year`) %>% 
  summarise(avg_Suicide_Rate = mean(`Suicide_Rate`, na.rm = T))

avg_Suicide_Rate_per_year

Plot

ggplot(avg_Suicide_Rate_per_year, aes(x = Year, y = avg_Suicide_Rate)) +
  geom_line(color = "blue") +  
  labs(title = "Average Suicide Rate Over Time worldwide",
       x = "Year",
       y = "Suicide Rate") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_Suicide_Rate_per_year$Year), max(avg_Suicide_Rate_per_year$Year), by = 1))

AVG Bankruptcies over years

Calculation

avg_Bankruptcies_per_year <- data %>% 
  group_by (`Year`) %>% 
  summarise(avg_Bankruptcies = mean(`Value`, na.rm = T))

avg_Bankruptcies_per_year

Plot

ggplot(avg_Bankruptcies_per_year, aes(x = Year, y = avg_Bankruptcies)) +
  geom_line(color = "blue") +  
  labs(title = "Average Bankruptcies Over Time worldwide",
       x = "Year",
       y = "Bankruptcies") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_Bankruptcies_per_year$Year), max(avg_Bankruptcies_per_year$Year), by = 1))

Plot Average GDP and Average Suicide Rate over years

# Finding the ratio for scaling the second axis
ratio <- max(avg_gdp_per_year$avg_gpd) / max(avg_Suicide_Rate_per_year$avg_Suicide_Rate)

# Creating the base plot
ggplot() +
  # Adding the bar plot for GDP
  geom_bar(data = avg_gdp_per_year, aes(x = Year, y = avg_gpd), stat = "identity", fill = "skyblue", width = 0.2) +
  # Adding the line plot for Average Happiness
  geom_line(data = avg_Suicide_Rate_per_year, aes(x = Year, y = avg_Suicide_Rate * ratio), color = "red", size = 1.5) +
  # Enhancing the plot
  labs(title = "Average GDP and Suicide Rate Over Time",
       x = "Year",
       y = "Average GDP") +
  scale_y_continuous(sec.axis = sec_axis(~ . / ratio, name = "Average Suicide Rate")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(c(avg_gdp_per_year$Year, avg_Suicide_Rate_per_year$Year)), 
                                  max(c(avg_gdp_per_year$Year, avg_Suicide_Rate_per_year$Year)), by = 1))

Plot Average Happinness and Average Suicide Rate over years

# Finding the ratio for scaling the second axis
ratio <- max(avg_happiness_per_year$avg_happinnes) / max(avg_Suicide_Rate_per_year$avg_Suicide_Rate)

# Creating the base plot
ggplot() +
  # Adding the bar plot for GDP
  geom_bar(data = avg_happiness_per_year, aes(x = Year, y = avg_happinnes), stat = "identity", fill = "skyblue", width = 0.2) +
  # Adding the line plot for Average Happiness
  geom_line(data = avg_Suicide_Rate_per_year, aes(x = Year, y = avg_Suicide_Rate * ratio), color = "red", size = 1.5) +
  # Enhancing the plot
  labs(title = "Average Happinness and Suicide Rate Over Time",
       x = "Year",
       y = "Average Happinness") +
  scale_y_continuous(sec.axis = sec_axis(~ . / ratio, name = "Average Suicide Rate")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(c(avg_happiness_per_year$Year, avg_Suicide_Rate_per_year$Year)), 
                                  max(c(avg_happiness_per_year$Year, avg_Suicide_Rate_per_year$Year)), by = 1))

Plot Average Bankruptcies and Average Suicide Rate over years

# Finding the ratio for scaling the second axis
ratio <- max(avg_Bankruptcies_per_year$avg_Bankruptcies) / max(avg_Suicide_Rate_per_year$avg_Suicide_Rate)

# Creating the base plot
ggplot() +
  # Adding the bar plot for GDP
  geom_bar(data = avg_Bankruptcies_per_year, aes(x = Year, y = avg_Bankruptcies), stat = "identity", fill = "skyblue", width = 0.2) +
  # Adding the line plot for Average Happiness
  geom_line(data = avg_Suicide_Rate_per_year, aes(x = Year, y = avg_Suicide_Rate * ratio), color = "red", size = 1.5) +
  # Enhancing the plot
  labs(title = "Average Bankruptcies and Suicide Rate Over Time",
       x = "Year",
       y = "Average Bankruptcies") +
  scale_y_continuous(sec.axis = sec_axis(~ . / ratio, name = "Average Suicide Rate")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(c(avg_Bankruptcies_per_year$Year, avg_Suicide_Rate_per_year$Year)), 
                                  max(c(avg_Bankruptcies_per_year$Year, avg_Suicide_Rate_per_year$Year)), by = 1))

Comparisions

Two Happiest and Two unhappiest countries vs suicide rate

avg_Suicide_Rate_per_country = data %>%
  group_by(Country_name) %>%
  summarise(avg_suicide_rate = mean(Suicide_Rate, na.rm = TRUE)) %>%
  arrange(avg_suicide_rate) %>% 
  mutate(Row_Number = row_number())

avg_Suicide_Rate_per_country

avg_happiness_per_country <- data %>%
  group_by(Country_name) %>%
  summarise(avg_happiness = mean(Life_ladder, na.rm = TRUE)) %>%
  arrange(desc(avg_happiness))

least_happy =  tail(avg_happiness_per_country, 2)
most_happy = head(avg_happiness_per_country, 2)


avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% least_happy$Country_name)

# Interpretation: Japan and South Africa are two very unhappy countries. And they also have a high suicide rate

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% most_happy$Country_name)

# Interpretation: Finland is a the second most happy country. But is still on place 16/19 when it comes to suicides

Two most wealthy countries and two most poor countries vs suicide rate

avg_gdp_per_country <- data %>% 
  group_by (`Country_name`) %>% 
  summarise(avg_gpd = mean(`GDP`)) %>% 
  arrange(desc(avg_gpd))

least_gdp =  tail(avg_gdp_per_country, 2)
most_gdp = head(avg_gdp_per_country, 2)

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% least_money$Country_name)

# Interpretation: New Zealand and Iceland are two very small countries.  

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% most_money$Country_name)

# Interpretation: The two biggest economies are based on the lower end of suicide rates

Two most bankcuptcies and two least bankcuptcies countries vs suicide rate


avg_Bankruptcies_per_year <- data %>% 
  group_by (`Country_name`) %>% 
  summarise(avg_bankruptcies = mean(`Value`, na.rm = T)) %>% 
  arrange(desc(avg_bankruptcies))

least_bank =  tail(avg_Bankruptcies_per_year, 2)
most_bank = head(avg_Bankruptcies_per_year, 2)

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% least_bank$Country_name)

# Interpretation: Bankruptcies don't have an influence on suicide rates

avg_Suicide_Rate_per_country %>% 
  filter(Country_name %in% most_bank$Country_name)

# Interpretation: Bankruptcies don't have an influence on suicide rates

In depth analysis Germany

Data preperation for Germany

# Prepare data for only Germany
germany_data = data %>% 
  filter(Country_name == "Germany")

Plot GDP Germany

# Plot Germany GDP over Years
avg_gdp_year_germany = germany_data %>% 
  group_by(Year) %>% 
  summarise(avg_gdp = mean(GDP)) 


ggplot(avg_gdp_year_germany, aes(x = Year, y = avg_gdp)) +
  geom_line(color = "blue") +  
  labs(title = "Average GPD Over Time - Germany",
       x = "Year",
       y = "GDP") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_gdp_year_germany$Year), max(avg_gdp_year_germany$Year), by = 1))

Plot Suicide Rate Germany

avg_suicide_year_germany = germany_data %>% 
  group_by(Year) %>% 
  summarise(avg_suicide = mean(Suicide_Rate)) 


ggplot(avg_suicide_year_germany, aes(x = Year, y = avg_suicide)) +
  geom_line(color = "blue") +  
  labs(title = "Average Suicide Rate Over Time - Germany",
       x = "Year",
       y = "Suicide Rate") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_suicide_year_germany$Year), max(avg_suicide_year_germany$Year), by = 1))

Plot Bankruptcies Rate Germany

avg_bank_year_germany = germany_data %>% 
  group_by(Year) %>% 
  summarise(avg_bank = mean(Value)) 


ggplot(avg_bank_year_germany, aes(x = Year, y = avg_bank)) +
  geom_line(color = "blue") +  
  labs(title = "Average bankruptcies Over Time - Germany",
       x = "Year",
       y = "Bankruptcies") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_bank_year_germany$Year), max(avg_bank_year_germany$Year), by = 1))

Plot Happiness Rate Germany

avg_happiness_year_germany = germany_data %>% 
  group_by(Year) %>% 
  summarise(avg_happy = mean(Life_ladder)) 


ggplot(avg_happiness_year_germany, aes(x = Year, y = avg_happy)) +
  geom_line(color = "blue") +  
  labs(title = "Average Happiness Over Time - Germany",
       x = "Year",
       y = "Happiness") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_happiness_year_germany$Year), max(avg_happiness_year_germany$Year), by = 1))

In depth analysis South Africa

Data preperation for South Africa

# Prepare data for only Germany
SA_data = data %>% 
  filter(Country_name == "South Africa")

Plot GDP SA

# Plot Germany GDP over Years
avg_gdp_year_SA = SA_data %>% 
  group_by(Year) %>% 
  summarise(avg_gdp = mean(GDP)) 



ggplot(avg_gdp_year_SA, aes(x = Year, y = avg_gdp)) +
  geom_line(color = "blue") +  
  labs(title = "Average GPD Over Time - SA",
       x = "Year",
       y = "GDP") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_gdp_year_SA$Year), max(avg_gdp_year_SA$Year), by = 1))

Plot Suicide Rate SA

avg_suicide_year_SA = SA_data %>% 
  group_by(Year) %>% 
  summarise(avg_suicide = mean(Suicide_Rate)) 


ggplot(avg_suicide_year_SA, aes(x = Year, y = avg_suicide)) +
  geom_line(color = "blue") +  
  labs(title = "Average Suicide Rate Over Time - SA",
       x = "Year",
       y = "Suicide Rate") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_suicide_year_SA$Year), max(avg_suicide_year_SA$Year), by = 1))

Plot Happiness Rate SA

avg_happiness_year_SA = SA_data %>% 
  group_by(Year) %>% 
  summarise(avg_happy = mean(Life_ladder)) 


ggplot(avg_happiness_year_SA, aes(x = Year, y = avg_happy)) +
  geom_line(color = "blue") +  
  labs(title = "Average Happiness Over Time - SA",
       x = "Year",
       y = "Happiness") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_happiness_year_SA$Year), max(avg_happiness_year_SA$Year), by = 1))

Plot Bankruptcies Rate SA

avg_bank_year_SA = SA_data %>% 
  group_by(Year) %>% 
  summarise(avg_bank = mean(Value)) 


ggplot(avg_bank_year_SA, aes(x = Year, y = avg_bank)) +
  geom_line(color = "blue") +  
  labs(title = "Average bankruptcies Over Time - SA",
       x = "Year",
       y = "Bankruptcies") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_continuous(breaks = seq(min(avg_bank_year_SA$Year), max(avg_bank_year_SA$Year), by = 1))

LS0tCnRpdGxlOiAiZWRhX3Byb2plY3QiCmF1dGhvcjogIk1hcmNrZW5yb2xkIENhZGV0IgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDogCiAgIGh0bWxfbm90ZWJvb2s6CiAgICAgICB0b2M6IHRydWUgCiAgICAgICB0b2NfZmxvYXQ6IHRydWUKICAgICAgIHRvY19kZXB0aDogMgogICAgICAgdGhlbWU6IHVuaXRlZAogICAgICAgaGlnaGxpZ2h0OiB0YW5nbwotLS0KCmBgYHtyfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGhpZ2hjaGFydGVyKQpsaWJyYXJ5KG1hZ3JpdHRyKQpgYGAKCgpgYGB7cn0KZGF0YSA8LSByZWFkX2NzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0FsZXhidXJrOTMvRGF0YV9XcmFuZ2xpbmdfRURBL21haW4vZGF0YS9zdWljaWRlX2FuYWx5c2lzLmNzdiIpCiAgICAgICAgICAgICAgICBkYXRhICU+JSBzYW1wbGVfbigxOSkKYGBgClJlbmFtaW5nIHZhcmlhYmxlcyBhbmQgZHJvcCB1bndhbnRlZCBjb2x1bW5zCmBgYHtyfQojIHJlbmFtaW5nIHRoZSBjb2x1bW5zIApkYXRhIDwtIGRhdGEgJT4lCiAgcmVuYW1lKGBDb3VudHJ5X25hbWVgID0gYENvdW50cnkgbmFtZWAsCiAgICAgICAgIGBTdWljaWRlX1JhdGVgID0gYEFnZS1zdGFuZGFyZGl6ZWQgc3VpY2lkZSByYXRlIC0gU2V4OiBib3RoIHNleGVzYCwKICAgICAgICAgYExpZmVfbGFkZGVyYCA9IGBMaWZlIExhZGRlcmAsCiAgICAgICAgIGBTb2NpYWxfc3VwcG9ydGAgPSBgU29jaWFsIHN1cHBvcnRgLAogICAgICAgICBgTGlmZV9leHBlY3RhbmN5YCA9IGBIZWFsdGh5IGxpZmUgZXhwZWN0YW5jeSBhdCBiaXJ0aGAsCiAgICAgICAgIGBGcmVlZG9tX2Nob2ljZXNgID0gYEZyZWVkb20gdG8gbWFrZSBsaWZlIGNob2ljZXNgLAogICAgICAgICBgQ29ycnVwdGlvbmAgPSBgUGVyY2VwdGlvbnMgb2YgY29ycnVwdGlvbmAsCiAgICAgICAgIGBJbmRpY2F0b3JfbmFtZWAgPSBgSW5kaWNhdG9yIE5hbWVgLAogICAgICAgICBgSW5kaWNhdG9yX2NvZGVgID0gYEluZGljYXRvciBDb2RlYCkKCiMgZHJvcCBjb2x1bW5zIAojIHJlbW92ZSB0aGUgb3JpZ2luYWwgJ1RpbWUnIGNvbHVtbgpkYXRhIDwtIHNlbGVjdChkYXRhLCAtVmFyaWFibGUsIC1JU0lDNC4uLjE3LCAtSVNJQzQuLi4xOCwgLVZBUiwgLU1FQSwgLWBVbml0IENvZGVgKSAgCmRhdGEKYGBgCmBgYHtyfQpoZWFkKGRhdGEpCmBgYAoKYGBge3J9CiMgY2hhbmdlIG5hbWVzCm5hbWVzKGRhdGEpIDwtIG1ha2UubmFtZXMobmFtZXMoZGF0YSkpCmBgYAoKYGBge3J9CiMgZGltZW5zaW9ucyBvZiB0aGUgZGF0YWZyYW1lCm5yb3coZGF0YSkKbmNvbChkYXRhKQpkaW0oZGF0YSkKYGBgCgpgYGB7cn0KIyBjaGVjayB0aGUgc3RydWN0dXJlIG9mIHRoZSBvYmplY3QKc3RyKGRhdGEpCmBgYApgYGB7cn0KIyBsb29rIGF0IGNvbHVtbnMgNiwgNyBhbmQgMTAKaGVhZChkYXRhWyAsIGMoMiwgNDo2LCAxMiwgMTUpXSkKYGBgCgpgYGB7cn0KIyBsb29rIGF0IGNvbHVtbnMgNiwgNyBhbmQgMTAKdGFpbChkYXRhWyAsIGMoMSwgMywgOSldKQpgYGAKCmBgYHtyfQp0YWJsZShkYXRhJFllYXIpCmBgYAoKCmBgYHtyfQpkYXRhICU+JSAKICBzZWxlY3QoQ291bnRyeV9uYW1lKSAlPiUgCiAgdW5pcXVlKCkgJT4lIAogIG5yb3coKQpgYGAKCmBgYHtyfQp1bmlxdWUoZGF0YSRDb3VudHJ5X25hbWUpCmBgYAoKYGBge3J9CnVuaXF1ZShkYXRhJFllYXIpCmBgYAoKCmBgYHtyfQojIFNldCBoaWdoY2hhcnRlciBvcHRpb25zIGZvciB0b29sdGlwIGRlY2ltYWxzCm9wdGlvbnMoaGlnaGNoYXJ0ZXIudG9vbHRpcC52YWx1ZURlY2ltYWxzID0gMikKCiMgQ3JlYXRlIGhpZ2hjaGFydGVyIG1hcCB2aXN1YWxpemF0aW9uCmhjIDwtIGhpZ2hjaGFydCgpICU+JQogIGhjX2FkZF9zZXJpZXNfbWFwKAogICAgd29ybGRnZW9qc29uLCBkYXRhLCB2YWx1ZSA9ICJHRFAiLCAKICAgIGpvaW5CeSA9IGMoJ25hbWUnLCAnQ291bnRyeV9uYW1lJyksCiAgICBuYW1lID0gIkdEUCAoY3VycmVudCBVUyQpIgogICkgICU+JSAKICBoY19jb2xvckF4aXMoc3RvcHMgPSBjb2xvcl9zdG9wcygpKSAlPiUgCiAgaGNfdGl0bGUodGV4dCA9ICJXb3JsZCBNYXAiKSAlPiUgCiAgaGNfc3VidGl0bGUodGV4dCA9ICJHRFAgaW4gY3VycmVudCBVUyQiKQoKaGMKYGBgCgpgYGB7cn0KIyBTZXQgaGlnaGNoYXJ0ZXIgb3B0aW9ucyBmb3IgdG9vbHRpcCBkZWNpbWFscwpvcHRpb25zKGhpZ2hjaGFydGVyLnRvb2x0aXAudmFsdWVEZWNpbWFscyA9IDIpCgojIENyZWF0ZSBtYXAgdmlzdWFsaXphdGlvbnMgZm9yIGVhY2ggdmFyaWFibGUKaGNfbGlmZV9leHBlY3RhbmN5IDwtIGhpZ2hjaGFydCgpICU+JQogIGhjX2FkZF9zZXJpZXNfbWFwKAogICAgd29ybGRnZW9qc29uLCBkYXRhLCAKICAgIHZhbHVlID0gIkxpZmVfZXhwZWN0YW5jeSIsIAogICAgam9pbkJ5ID0gYygnbmFtZScsICdDb3VudHJ5X25hbWUnKSwKICAgIG5hbWUgPSAiTGlmZSBFeHBlY3RhbmN5IgogICkgJT4lCiAgaGNfY29sb3JBeGlzKHN0b3BzID0gY29sb3Jfc3RvcHMoKSkgJT4lCiAgaGNfdGl0bGUodGV4dCA9ICJXb3JsZCBNYXAiKSAlPiUKICBoY19zdWJ0aXRsZSh0ZXh0ID0gIkxpZmUgRXhwZWN0YW5jeSIpCgpoY19zdWljaWRlX3JhdGVzIDwtIGhpZ2hjaGFydCgpICU+JQogIGhjX2FkZF9zZXJpZXNfbWFwKAogICAgd29ybGRnZW9qc29uLCBkYXRhLCAKICAgIHZhbHVlID0gIlN1aWNpZGVfUmF0ZSIsIAogICAgam9pbkJ5ID0gYygnbmFtZScsICdDb3VudHJ5X25hbWUnKSwKICAgIG5hbWUgPSAiU3VpY2lkZSBSYXRlcyIKICApICU+JQogIGhjX2NvbG9yQXhpcyhzdG9wcyA9IGNvbG9yX3N0b3BzKCkpICU+JQogIGhjX3RpdGxlKHRleHQgPSAiV29ybGQgTWFwIikgJT4lCiAgaGNfc3VidGl0bGUodGV4dCA9ICJTdWljaWRlIFJhdGUiKQoKaGNfY29ycnVwdGlvbiA8LSBoaWdoY2hhcnQoKSAlPiUKICBoY19hZGRfc2VyaWVzX21hcCgKICAgIHdvcmxkZ2VvanNvbiwgZGF0YSwgCiAgICB2YWx1ZSA9ICJDb3JydXB0aW9uIiwgCiAgICBqb2luQnkgPSBjKCduYW1lJywgJ0NvdW50cnlfbmFtZScpLAogICAgbmFtZSA9ICJDb3JydXB0aW9uIgogICkgJT4lCiAgaGNfY29sb3JBeGlzKHN0b3BzID0gY29sb3Jfc3RvcHMoKSkgJT4lCiAgaGNfdGl0bGUodGV4dCA9ICJXb3JsZCBNYXAiKSAlPiUKICBoY19zdWJ0aXRsZSh0ZXh0ID0gIkNvcnJ1cHRpb24iKQoKIyBEaXNwbGF5IHRoZSBtYXAgdmlzdWFsaXphdGlvbnMKbGlzdChoY19saWZlX2V4cGVjdGFuY3ksIGhjX3N1aWNpZGVfcmF0ZXMsIGhjX2NvcnJ1cHRpb24pCgpgYGAKCiMgQVZHIEdEUCBvdmVyIHllYXJzCiMjIENhbGN1bGF0aW9uIApgYGB7cn0KYXZnX2dkcF9wZXJfeWVhciA8LSBkYXRhICU+JSAKICBncm91cF9ieSAoYFllYXJgKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19ncGQgPSBtZWFuKGBHRFBgKSkKCmF2Z19nZHBfcGVyX3llYXIKYGBgCiMjIFBsb3QgCmBgYHtyfQpnZ3Bsb3QoYXZnX2dkcF9wZXJfeWVhciwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX2dwZCkpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsgIAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBHRFAgT3ZlciBUaW1lIHdvcmxkd2lkZSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJHRFAiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX2dkcF9wZXJfeWVhciRZZWFyKSwgbWF4KGF2Z19nZHBfcGVyX3llYXIkWWVhciksIGJ5ID0gMSkpCmBgYAojIEFWRyBIYXBwaW5lc3Mgb3ZlciB5ZWFycwojIyBDYWxjdWxhdGlvbiAKYGBge3J9CmF2Z19oYXBwaW5lc3NfcGVyX3llYXIgPC0gZGF0YSAlPiUgCiAgZ3JvdXBfYnkgKGBZZWFyYCkgJT4lIAogIHN1bW1hcmlzZShhdmdfaGFwcGlubmVzID0gbWVhbihgTGlmZV9sYWRkZXJgLCBuYS5ybSA9IFQpKQoKYXZnX2hhcHBpbmVzc19wZXJfeWVhcgpgYGAKIyMgUGxvdCAKCmBgYHtyfQpnZ3Bsb3QoYXZnX2hhcHBpbmVzc19wZXJfeWVhciwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX2hhcHBpbm5lcykpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsgIAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBIYXBwaW5lc3MgT3ZlciBUaW1lIHdvcmxkd2lkZSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJIYXBwaW5lc3MiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX2hhcHBpbmVzc19wZXJfeWVhciRZZWFyKSwgbWF4KGF2Z19oYXBwaW5lc3NfcGVyX3llYXIkWWVhciksIGJ5ID0gMSkpCmBgYAoKIyBBVkcgU3VpY2lkZSBSYXRlcyBvdmVyIHllYXJzCiMjIENhbGN1bGF0aW9uIApgYGB7cn0KYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciA8LSBkYXRhICU+JSAKICBncm91cF9ieSAoYFllYXJgKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19TdWljaWRlX1JhdGUgPSBtZWFuKGBTdWljaWRlX1JhdGVgLCBuYS5ybSA9IFQpKQoKYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhcgpgYGAKIyMgUGxvdCAKCmBgYHtyfQpnZ3Bsb3QoYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX1N1aWNpZGVfUmF0ZSkpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsgIAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBTdWljaWRlIFJhdGUgT3ZlciBUaW1lIHdvcmxkd2lkZSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJTdWljaWRlIFJhdGUiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciRZZWFyKSwgbWF4KGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIkWWVhciksIGJ5ID0gMSkpCmBgYAojIEFWRyBCYW5rcnVwdGNpZXMgb3ZlciB5ZWFycwojIyBDYWxjdWxhdGlvbiAKYGBge3J9CmF2Z19CYW5rcnVwdGNpZXNfcGVyX3llYXIgPC0gZGF0YSAlPiUgCiAgZ3JvdXBfYnkgKGBZZWFyYCkgJT4lIAogIHN1bW1hcmlzZShhdmdfQmFua3J1cHRjaWVzID0gbWVhbihgVmFsdWVgLCBuYS5ybSA9IFQpKQoKYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhcgpgYGAKIyMgUGxvdCAKCmBgYHtyfQpnZ3Bsb3QoYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX0JhbmtydXB0Y2llcykpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsgIAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBCYW5rcnVwdGNpZXMgT3ZlciBUaW1lIHdvcmxkd2lkZSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJCYW5rcnVwdGNpZXMiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciRZZWFyKSwgbWF4KGF2Z19CYW5rcnVwdGNpZXNfcGVyX3llYXIkWWVhciksIGJ5ID0gMSkpCmBgYAoKIyBQbG90IEF2ZXJhZ2UgR0RQIGFuZCBBdmVyYWdlIFN1aWNpZGUgUmF0ZSBvdmVyIHllYXJzCmBgYHtyfQojIEZpbmRpbmcgdGhlIHJhdGlvIGZvciBzY2FsaW5nIHRoZSBzZWNvbmQgYXhpcwpyYXRpbyA8LSBtYXgoYXZnX2dkcF9wZXJfeWVhciRhdmdfZ3BkKSAvIG1heChhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyJGF2Z19TdWljaWRlX1JhdGUpCgojIENyZWF0aW5nIHRoZSBiYXNlIHBsb3QKZ2dwbG90KCkgKwogICMgQWRkaW5nIHRoZSBiYXIgcGxvdCBmb3IgR0RQCiAgZ2VvbV9iYXIoZGF0YSA9IGF2Z19nZHBfcGVyX3llYXIsIGFlcyh4ID0gWWVhciwgeSA9IGF2Z19ncGQpLCBzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJza3libHVlIiwgd2lkdGggPSAwLjIpICsKICAjIEFkZGluZyB0aGUgbGluZSBwbG90IGZvciBBdmVyYWdlIEhhcHBpbmVzcwogIGdlb21fbGluZShkYXRhID0gYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX1N1aWNpZGVfUmF0ZSAqIHJhdGlvKSwgY29sb3IgPSAicmVkIiwgc2l6ZSA9IDEuNSkgKwogICMgRW5oYW5jaW5nIHRoZSBwbG90CiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEdEUCBhbmQgU3VpY2lkZSBSYXRlIE92ZXIgVGltZSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJBdmVyYWdlIEdEUCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoc2VjLmF4aXMgPSBzZWNfYXhpcyh+IC4gLyByYXRpbywgbmFtZSA9ICJBdmVyYWdlIFN1aWNpZGUgUmF0ZSIpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYyhhdmdfZ2RwX3Blcl95ZWFyJFllYXIsIGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIkWWVhcikpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChjKGF2Z19nZHBfcGVyX3llYXIkWWVhciwgYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciRZZWFyKSksIGJ5ID0gMSkpCgpgYGAKCiMgUGxvdCBBdmVyYWdlIEhhcHBpbm5lc3MgYW5kIEF2ZXJhZ2UgU3VpY2lkZSBSYXRlIG92ZXIgeWVhcnMKYGBge3J9CiMgRmluZGluZyB0aGUgcmF0aW8gZm9yIHNjYWxpbmcgdGhlIHNlY29uZCBheGlzCnJhdGlvIDwtIG1heChhdmdfaGFwcGluZXNzX3Blcl95ZWFyJGF2Z19oYXBwaW5uZXMpIC8gbWF4KGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIkYXZnX1N1aWNpZGVfUmF0ZSkKCiMgQ3JlYXRpbmcgdGhlIGJhc2UgcGxvdApnZ3Bsb3QoKSArCiAgIyBBZGRpbmcgdGhlIGJhciBwbG90IGZvciBHRFAKICBnZW9tX2JhcihkYXRhID0gYXZnX2hhcHBpbmVzc19wZXJfeWVhciwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX2hhcHBpbm5lcyksIHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInNreWJsdWUiLCB3aWR0aCA9IDAuMikgKwogICMgQWRkaW5nIHRoZSBsaW5lIHBsb3QgZm9yIEF2ZXJhZ2UgSGFwcGluZXNzCiAgZ2VvbV9saW5lKGRhdGEgPSBhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfU3VpY2lkZV9SYXRlICogcmF0aW8pLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMS41KSArCiAgIyBFbmhhbmNpbmcgdGhlIHBsb3QKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgSGFwcGlubmVzcyBhbmQgU3VpY2lkZSBSYXRlIE92ZXIgVGltZSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJBdmVyYWdlIEhhcHBpbm5lc3MiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofiAuIC8gcmF0aW8sIG5hbWUgPSAiQXZlcmFnZSBTdWljaWRlIFJhdGUiKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKGMoYXZnX2hhcHBpbmVzc19wZXJfeWVhciRZZWFyLCBhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyJFllYXIpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgoYyhhdmdfaGFwcGluZXNzX3Blcl95ZWFyJFllYXIsIGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIkWWVhcikpLCBieSA9IDEpKQoKYGBgCgojIFBsb3QgQXZlcmFnZSBCYW5rcnVwdGNpZXMgYW5kIEF2ZXJhZ2UgU3VpY2lkZSBSYXRlIG92ZXIgeWVhcnMKYGBge3J9CiMgRmluZGluZyB0aGUgcmF0aW8gZm9yIHNjYWxpbmcgdGhlIHNlY29uZCBheGlzCnJhdGlvIDwtIG1heChhdmdfQmFua3J1cHRjaWVzX3Blcl95ZWFyJGF2Z19CYW5rcnVwdGNpZXMpIC8gbWF4KGF2Z19TdWljaWRlX1JhdGVfcGVyX3llYXIkYXZnX1N1aWNpZGVfUmF0ZSkKCiMgQ3JlYXRpbmcgdGhlIGJhc2UgcGxvdApnZ3Bsb3QoKSArCiAgIyBBZGRpbmcgdGhlIGJhciBwbG90IGZvciBHRFAKICBnZW9tX2JhcihkYXRhID0gYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX0JhbmtydXB0Y2llcyksIHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInNreWJsdWUiLCB3aWR0aCA9IDAuMikgKwogICMgQWRkaW5nIHRoZSBsaW5lIHBsb3QgZm9yIEF2ZXJhZ2UgSGFwcGluZXNzCiAgZ2VvbV9saW5lKGRhdGEgPSBhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfU3VpY2lkZV9SYXRlICogcmF0aW8pLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMS41KSArCiAgIyBFbmhhbmNpbmcgdGhlIHBsb3QKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgQmFua3J1cHRjaWVzIGFuZCBTdWljaWRlIFJhdGUgT3ZlciBUaW1lIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgQmFua3J1cHRjaWVzIikgKwogIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4gLiAvIHJhdGlvLCBuYW1lID0gIkF2ZXJhZ2UgU3VpY2lkZSBSYXRlIikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihjKGF2Z19CYW5rcnVwdGNpZXNfcGVyX3llYXIkWWVhciwgYXZnX1N1aWNpZGVfUmF0ZV9wZXJfeWVhciRZZWFyKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KGMoYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciRZZWFyLCBhdmdfU3VpY2lkZV9SYXRlX3Blcl95ZWFyJFllYXIpKSwgYnkgPSAxKSkKCmBgYAoKIyBDb21wYXJpc2lvbnMKCiMjIFR3byBIYXBwaWVzdCBhbmQgVHdvIHVuaGFwcGllc3QgY291bnRyaWVzIHZzIHN1aWNpZGUgcmF0ZQpgYGB7cn0KYXZnX1N1aWNpZGVfUmF0ZV9wZXJfY291bnRyeSA9IGRhdGEgJT4lCiAgZ3JvdXBfYnkoQ291bnRyeV9uYW1lKSAlPiUKICBzdW1tYXJpc2UoYXZnX3N1aWNpZGVfcmF0ZSA9IG1lYW4oU3VpY2lkZV9SYXRlLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBhcnJhbmdlKGF2Z19zdWljaWRlX3JhdGUpICU+JSAKICBtdXRhdGUoUm93X051bWJlciA9IHJvd19udW1iZXIoKSkKCmF2Z19TdWljaWRlX1JhdGVfcGVyX2NvdW50cnkKCmF2Z19oYXBwaW5lc3NfcGVyX2NvdW50cnkgPC0gZGF0YSAlPiUKICBncm91cF9ieShDb3VudHJ5X25hbWUpICU+JQogIHN1bW1hcmlzZShhdmdfaGFwcGluZXNzID0gbWVhbihMaWZlX2xhZGRlciwgbmEucm0gPSBUUlVFKSkgJT4lCiAgYXJyYW5nZShkZXNjKGF2Z19oYXBwaW5lc3MpKQoKbGVhc3RfaGFwcHkgPSAgdGFpbChhdmdfaGFwcGluZXNzX3Blcl9jb3VudHJ5LCAyKQptb3N0X2hhcHB5ID0gaGVhZChhdmdfaGFwcGluZXNzX3Blcl9jb3VudHJ5LCAyKQoKCmF2Z19TdWljaWRlX1JhdGVfcGVyX2NvdW50cnkgJT4lIAogIGZpbHRlcihDb3VudHJ5X25hbWUgJWluJSBsZWFzdF9oYXBweSRDb3VudHJ5X25hbWUpCgojIEludGVycHJldGF0aW9uOiBKYXBhbiBhbmQgU291dGggQWZyaWNhIGFyZSB0d28gdmVyeSB1bmhhcHB5IGNvdW50cmllcy4gQW5kIHRoZXkgYWxzbyBoYXZlIGEgaGlnaCBzdWljaWRlIHJhdGUKCmF2Z19TdWljaWRlX1JhdGVfcGVyX2NvdW50cnkgJT4lIAogIGZpbHRlcihDb3VudHJ5X25hbWUgJWluJSBtb3N0X2hhcHB5JENvdW50cnlfbmFtZSkKCiMgSW50ZXJwcmV0YXRpb246IEZpbmxhbmQgaXMgYSB0aGUgc2Vjb25kIG1vc3QgaGFwcHkgY291bnRyeS4gQnV0IGlzIHN0aWxsIG9uIHBsYWNlIDE2LzE5IHdoZW4gaXQgY29tZXMgdG8gc3VpY2lkZXMKCmBgYAoKIyMgVHdvIG1vc3Qgd2VhbHRoeSBjb3VudHJpZXMgYW5kIHR3byBtb3N0IHBvb3IgY291bnRyaWVzIHZzIHN1aWNpZGUgcmF0ZQpgYGB7cn0KYXZnX2dkcF9wZXJfY291bnRyeSA8LSBkYXRhICU+JSAKICBncm91cF9ieSAoYENvdW50cnlfbmFtZWApICU+JSAKICBzdW1tYXJpc2UoYXZnX2dwZCA9IG1lYW4oYEdEUGApKSAlPiUgCiAgYXJyYW5nZShkZXNjKGF2Z19ncGQpKQoKbGVhc3RfZ2RwID0gIHRhaWwoYXZnX2dkcF9wZXJfY291bnRyeSwgMikKbW9zdF9nZHAgPSBoZWFkKGF2Z19nZHBfcGVyX2NvdW50cnksIDIpCgphdmdfU3VpY2lkZV9SYXRlX3Blcl9jb3VudHJ5ICU+JSAKICBmaWx0ZXIoQ291bnRyeV9uYW1lICVpbiUgbGVhc3RfbW9uZXkkQ291bnRyeV9uYW1lKQoKIyBJbnRlcnByZXRhdGlvbjogTmV3IFplYWxhbmQgYW5kIEljZWxhbmQgYXJlIHR3byB2ZXJ5IHNtYWxsIGNvdW50cmllcy4gIAoKYXZnX1N1aWNpZGVfUmF0ZV9wZXJfY291bnRyeSAlPiUgCiAgZmlsdGVyKENvdW50cnlfbmFtZSAlaW4lIG1vc3RfbW9uZXkkQ291bnRyeV9uYW1lKQoKIyBJbnRlcnByZXRhdGlvbjogVGhlIHR3byBiaWdnZXN0IGVjb25vbWllcyBhcmUgYmFzZWQgb24gdGhlIGxvd2VyIGVuZCBvZiBzdWljaWRlIHJhdGVzCmBgYAoKCiMjIFR3byBtb3N0IGJhbmtjdXB0Y2llcyBhbmQgdHdvIGxlYXN0IGJhbmtjdXB0Y2llcyBjb3VudHJpZXMgdnMgc3VpY2lkZSByYXRlCmBgYHtyfQoKYXZnX0JhbmtydXB0Y2llc19wZXJfeWVhciA8LSBkYXRhICU+JSAKICBncm91cF9ieSAoYENvdW50cnlfbmFtZWApICU+JSAKICBzdW1tYXJpc2UoYXZnX2JhbmtydXB0Y2llcyA9IG1lYW4oYFZhbHVlYCwgbmEucm0gPSBUKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhhdmdfYmFua3J1cHRjaWVzKSkKCmxlYXN0X2JhbmsgPSAgdGFpbChhdmdfQmFua3J1cHRjaWVzX3Blcl95ZWFyLCAyKQptb3N0X2JhbmsgPSBoZWFkKGF2Z19CYW5rcnVwdGNpZXNfcGVyX3llYXIsIDIpCgphdmdfU3VpY2lkZV9SYXRlX3Blcl9jb3VudHJ5ICU+JSAKICBmaWx0ZXIoQ291bnRyeV9uYW1lICVpbiUgbGVhc3RfYmFuayRDb3VudHJ5X25hbWUpCgojIEludGVycHJldGF0aW9uOiBCYW5rcnVwdGNpZXMgZG9uJ3QgaGF2ZSBhbiBpbmZsdWVuY2Ugb24gc3VpY2lkZSByYXRlcwoKYXZnX1N1aWNpZGVfUmF0ZV9wZXJfY291bnRyeSAlPiUgCiAgZmlsdGVyKENvdW50cnlfbmFtZSAlaW4lIG1vc3RfYmFuayRDb3VudHJ5X25hbWUpCgojIEludGVycHJldGF0aW9uOiBCYW5rcnVwdGNpZXMgZG9uJ3QgaGF2ZSBhbiBpbmZsdWVuY2Ugb24gc3VpY2lkZSByYXRlcwpgYGAKIyBJbiBkZXB0aCBhbmFseXNpcyBHZXJtYW55CiMjIERhdGEgcHJlcGVyYXRpb24gZm9yIEdlcm1hbnkKYGBge3J9CiMgUHJlcGFyZSBkYXRhIGZvciBvbmx5IEdlcm1hbnkKZ2VybWFueV9kYXRhID0gZGF0YSAlPiUgCiAgZmlsdGVyKENvdW50cnlfbmFtZSA9PSAiR2VybWFueSIpCmBgYAoKIyMgUGxvdCBHRFAgR2VybWFueQpgYGB7cn0KIyBQbG90IEdlcm1hbnkgR0RQIG92ZXIgWWVhcnMKYXZnX2dkcF95ZWFyX2dlcm1hbnkgPSBnZXJtYW55X2RhdGEgJT4lIAogIGdyb3VwX2J5KFllYXIpICU+JSAKICBzdW1tYXJpc2UoYXZnX2dkcCA9IG1lYW4oR0RQKSkgCgoKZ2dwbG90KGF2Z19nZHBfeWVhcl9nZXJtYW55LCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfZ2RwKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEdQRCBPdmVyIFRpbWUgLSBHZXJtYW55IiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkdEUCIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfZ2RwX3llYXJfZ2VybWFueSRZZWFyKSwgbWF4KGF2Z19nZHBfeWVhcl9nZXJtYW55JFllYXIpLCBieSA9IDEpKQoKYGBgCgojIyBQbG90IFN1aWNpZGUgUmF0ZSBHZXJtYW55CmBgYHtyfQphdmdfc3VpY2lkZV95ZWFyX2dlcm1hbnkgPSBnZXJtYW55X2RhdGEgJT4lIAogIGdyb3VwX2J5KFllYXIpICU+JSAKICBzdW1tYXJpc2UoYXZnX3N1aWNpZGUgPSBtZWFuKFN1aWNpZGVfUmF0ZSkpIAoKCmdncGxvdChhdmdfc3VpY2lkZV95ZWFyX2dlcm1hbnksIGFlcyh4ID0gWWVhciwgeSA9IGF2Z19zdWljaWRlKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIFN1aWNpZGUgUmF0ZSBPdmVyIFRpbWUgLSBHZXJtYW55IiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIlN1aWNpZGUgUmF0ZSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfc3VpY2lkZV95ZWFyX2dlcm1hbnkkWWVhciksIG1heChhdmdfc3VpY2lkZV95ZWFyX2dlcm1hbnkkWWVhciksIGJ5ID0gMSkpCmBgYAojIyBQbG90IEJhbmtydXB0Y2llcyBSYXRlIEdlcm1hbnkKYGBge3J9CmF2Z19iYW5rX3llYXJfZ2VybWFueSA9IGdlcm1hbnlfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoWWVhcikgJT4lIAogIHN1bW1hcmlzZShhdmdfYmFuayA9IG1lYW4oVmFsdWUpKSAKCgpnZ3Bsb3QoYXZnX2JhbmtfeWVhcl9nZXJtYW55LCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfYmFuaykpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsgIAogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBiYW5rcnVwdGNpZXMgT3ZlciBUaW1lIC0gR2VybWFueSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJCYW5rcnVwdGNpZXMiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX2JhbmtfeWVhcl9nZXJtYW55JFllYXIpLCBtYXgoYXZnX2JhbmtfeWVhcl9nZXJtYW55JFllYXIpLCBieSA9IDEpKQpgYGAKIyMgUGxvdCBIYXBwaW5lc3MgUmF0ZSBHZXJtYW55CmBgYHtyfQphdmdfaGFwcGluZXNzX3llYXJfZ2VybWFueSA9IGdlcm1hbnlfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoWWVhcikgJT4lIAogIHN1bW1hcmlzZShhdmdfaGFwcHkgPSBtZWFuKExpZmVfbGFkZGVyKSkgCgoKZ2dwbG90KGF2Z19oYXBwaW5lc3NfeWVhcl9nZXJtYW55LCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfaGFwcHkpKSArCiAgZ2VvbV9saW5lKGNvbG9yID0gImJsdWUiKSArICAKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgSGFwcGluZXNzIE92ZXIgVGltZSAtIEdlcm1hbnkiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiSGFwcGluZXNzIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKGF2Z19oYXBwaW5lc3NfeWVhcl9nZXJtYW55JFllYXIpLCBtYXgoYXZnX2hhcHBpbmVzc195ZWFyX2dlcm1hbnkkWWVhciksIGJ5ID0gMSkpCmBgYAojIEluIGRlcHRoIGFuYWx5c2lzIFNvdXRoIEFmcmljYQojIyBEYXRhIHByZXBlcmF0aW9uIGZvciBTb3V0aCBBZnJpY2EKYGBge3J9CiMgUHJlcGFyZSBkYXRhIGZvciBvbmx5IEdlcm1hbnkKU0FfZGF0YSA9IGRhdGEgJT4lIAogIGZpbHRlcihDb3VudHJ5X25hbWUgPT0gIlNvdXRoIEFmcmljYSIpCmBgYAoKIyMgUGxvdCBHRFAgU0EKYGBge3J9CiMgUGxvdCBHZXJtYW55IEdEUCBvdmVyIFllYXJzCmF2Z19nZHBfeWVhcl9TQSA9IFNBX2RhdGEgJT4lIAogIGdyb3VwX2J5KFllYXIpICU+JSAKICBzdW1tYXJpc2UoYXZnX2dkcCA9IG1lYW4oR0RQKSkgCgoKCmdncGxvdChhdmdfZ2RwX3llYXJfU0EsIGFlcyh4ID0gWWVhciwgeSA9IGF2Z19nZHApKSArCiAgZ2VvbV9saW5lKGNvbG9yID0gImJsdWUiKSArICAKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgR1BEIE92ZXIgVGltZSAtIFNBIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkdEUCIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfZ2RwX3llYXJfU0EkWWVhciksIG1heChhdmdfZ2RwX3llYXJfU0EkWWVhciksIGJ5ID0gMSkpCgpgYGAKIyMgUGxvdCBTdWljaWRlIFJhdGUgU0EKYGBge3J9CmF2Z19zdWljaWRlX3llYXJfU0EgPSBTQV9kYXRhICU+JSAKICBncm91cF9ieShZZWFyKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19zdWljaWRlID0gbWVhbihTdWljaWRlX1JhdGUpKSAKCgpnZ3Bsb3QoYXZnX3N1aWNpZGVfeWVhcl9TQSwgYWVzKHggPSBZZWFyLCB5ID0gYXZnX3N1aWNpZGUpKSArCiAgZ2VvbV9saW5lKGNvbG9yID0gImJsdWUiKSArICAKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgU3VpY2lkZSBSYXRlIE92ZXIgVGltZSAtIFNBIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIlN1aWNpZGUgUmF0ZSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfc3VpY2lkZV95ZWFyX1NBJFllYXIpLCBtYXgoYXZnX3N1aWNpZGVfeWVhcl9TQSRZZWFyKSwgYnkgPSAxKSkKYGBgCgojIyBQbG90IEhhcHBpbmVzcyBSYXRlIFNBCmBgYHtyfQphdmdfaGFwcGluZXNzX3llYXJfU0EgPSBTQV9kYXRhICU+JSAKICBncm91cF9ieShZZWFyKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19oYXBweSA9IG1lYW4oTGlmZV9sYWRkZXIpKSAKCgpnZ3Bsb3QoYXZnX2hhcHBpbmVzc195ZWFyX1NBLCBhZXMoeCA9IFllYXIsIHkgPSBhdmdfaGFwcHkpKSArCiAgZ2VvbV9saW5lKGNvbG9yID0gImJsdWUiKSArICAKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgSGFwcGluZXNzIE92ZXIgVGltZSAtIFNBIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkhhcHBpbmVzcyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihhdmdfaGFwcGluZXNzX3llYXJfU0EkWWVhciksIG1heChhdmdfaGFwcGluZXNzX3llYXJfU0EkWWVhciksIGJ5ID0gMSkpCmBgYAoKIyMgUGxvdCBCYW5rcnVwdGNpZXMgUmF0ZSBTQQpgYGB7cn0KYXZnX2JhbmtfeWVhcl9TQSA9IFNBX2RhdGEgJT4lIAogIGdyb3VwX2J5KFllYXIpICU+JSAKICBzdW1tYXJpc2UoYXZnX2JhbmsgPSBtZWFuKFZhbHVlKSkgCgoKZ2dwbG90KGF2Z19iYW5rX3llYXJfU0EsIGFlcyh4ID0gWWVhciwgeSA9IGF2Z19iYW5rKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKyAgCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIGJhbmtydXB0Y2llcyBPdmVyIFRpbWUgLSBTQSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJCYW5rcnVwdGNpZXMiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oYXZnX2JhbmtfeWVhcl9TQSRZZWFyKSwgbWF4KGF2Z19iYW5rX3llYXJfU0EkWWVhciksIGJ5ID0gMSkpCmBgYA==